﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media.Animation;
using System.Runtime;

namespace System.Windows.Media.Media3D10
{
    /// <summary>
    /// Classe abstraite qui représente une valeur <see cref="SlimDX.Vector3"/> animée. 
    /// </summary>
    public abstract class Vector3AnimationBase : AnimationTimeline
    {
        /// <summary>
        /// Initialise une nouvelle instance de la classe <see cref="Vector3AnimationBase"/>
        /// </summary>
        [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
        protected Vector3AnimationBase()
        {
        
        }

        /// <summary>
        /// Obtient le type de valeur généré par cette animation
        /// </summary>
        public override Type TargetPropertyType
        {
            get { return typeof(SlimDX.Vector3); }
        }

        /// <summary>
        /// Crée un clone modifiable de ce <see cref="Vector3AnimationBase"/>, en créant des copies complètes des valeurs de cet objet.
        /// Lors de la copie de propriétés de dépendance, cette méthode copie les références de ressources et les liaisons de données (même si elles ne peuvent plus être résolues), mais pas les animations ni leurs valeurs actuelles.
        /// </summary>
        /// <returns>
        /// Clone modifiable de l'objet actuel.
        /// La valeur de la propriété <see cref="Freezable.IsFrozen"/> de l'objet cloné est false, même si la valeur de la propriété <see cref="Freezable.IsFrozen"/> de la source est true.
        /// </returns>
        public new Vector3AnimationBase Clone()
        {
            return base.Clone() as Vector3AnimationBase;
        }

        /// <summary>
        /// Obtient la valeur actuelle de l'animation.
        /// </summary>
        /// <param name="defaultOriginValue">Valeur d'origine attribuée à l'animation lorsque l'animation ne dispose pas de sa propre valeur de départ. </param>
        /// <param name="defaultDestinationValue">Valeur de destination attribuée à l'animation lorsque l'animation ne dispose pas de sa propre valeur de destination.</param>
        /// <param name="animationClock"><see cref="AnimationClock"/> qui permet de générer la valeur <see cref="Clock.CurrentTime"/> ou la valeur <see cref="Clock.CurrentProgress"/> utilisée par l'animation pour générer sa valeur de sortie.</param>
        /// <returns></returns>
        public override sealed object GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock)
        {
            SlimDX.Vector3? vectOrigin = defaultOriginValue as SlimDX.Vector3?;
            SlimDX.Vector3? vectDestination = defaultDestinationValue as SlimDX.Vector3?;
            if (!vectOrigin.HasValue)
                throw new ArgumentException("Parameter must be a SlimDX.Vector3", "defaultOriginValue");
            if (!vectDestination.HasValue)
                throw new ArgumentException("Parameter must be a SlimDX.Vector3", "defaultDestinationValue");
            SlimDX.Vector3 currentValue = this.GetCurrentValueCore(vectOrigin.Value, vectDestination.Value, animationClock);
            return currentValue;
        }

        /// <summary>
        /// Obtient la valeur actuelle de l'animation.
        /// </summary>
        /// <param name="defaultOriginValue">Valeur d'origine attribuée à l'animation lorsque l'animation ne dispose pas de sa propre valeur de départ. </param>
        /// <param name="defaultDestinationValue">Valeur de destination attribuée à l'animation lorsque l'animation ne dispose pas de sa propre valeur de destination.</param>
        /// <param name="animationClock"><see cref="AnimationClock"/> qui permet de générer la valeur <see cref="Clock.CurrentTime"/> ou la valeur <see cref="Clock.CurrentProgress"/> utilisée par l'animation pour générer sa valeur de sortie.</param>
        /// <returns></returns>
        public SlimDX.Vector3 GetCurrentValue(SlimDX.Vector3 defaultOriginValue, SlimDX.Vector3 defaultDestinationValue, AnimationClock animationClock)
        {
            SlimDX.Vector3 currentValue = this.GetCurrentValueCore(defaultOriginValue, defaultDestinationValue, animationClock);
            return currentValue;
        }

        /// <summary>
        /// Calcule une valeur qui correspond à la valeur actuelle de la propriété en cours d'animation, tel que déterminé par l'animation hôte. 
        /// </summary>
        /// <param name="defaultOriginValue">Valeur d'origine suggérée, utilisée si la valeur de départ de l'animation n'est pas explicitement définie.</param>
        /// <param name="defaultDestinationValue">Valeur de destination suggérée, utilisée si la valeur de fin de l'animation n'est pas explicitement définie.</param>
        /// <param name="animationClock"><see cref="AnimationClock"/> qui génère le <see cref="Clock.CurrentTime"/> ou <see cref="Clock.CurrentProgress"/> utilisé par l'animation hôte.</param>
        /// <returns>Valeur calculée de la propriété, déterminée par l'animation actuelle.</returns>
        protected abstract SlimDX.Vector3 GetCurrentValueCore(SlimDX.Vector3 defaultOriginValue, SlimDX.Vector3 defaultDestinationValue, AnimationClock animationClock);
    }
}
